這個東東主要的概念來自 Martin Fowler 所寫的 《 Presentation Model 》這篇文章,MVVM 基本上算是 PM ( Presentation Model ) 的變體,不過當初 PM 主要是以 GUI 為主撰寫,不太確定是否與 web 打架…
( 小備註: 這個人的 Blog 可以說是通往軟體架構師必看之 Blog )
接下來談談 MVVM 的三個主題
圖片來源: educative-Acing the JavaScript Design Patterns Interview
認真說,我第一眼看到就覺得,viewModel 的功能怎麼和 MVP 的 presenter 有點像呢 ? 這裡有幾個重點和 MVP 與 MVC 不太一樣。
這裡的範例我直接從 educative 內的範例來抓下重點部份來說明。
// Model
class Model {
constructor () {
this.model = { name: 'Mark' }
this.observers = []
}
subscribe (observer) {
this.observers.push(observer)
}
notifyObservers (attrName, newVal) {
for (let i = 0; i < this.observers.length; i++) {
this.observers[i](attrName, newVal)
}
}
getCurrentName (nameKey) {
return this.model[nameKey]
}
setNameValue (nameKey, value) {
this.model[nameKey] = value
this.notifyObservers(nameKey, value)
}
}
// ViewModel
class ViewModel {
constructor (model) {
this.bind = function (viewElement, modelElement) {
// 將 view element 與 model element 綁在一起。
viewElement.value = model.getCurrentName(modelElement)
// 當 view 有什麼事件時,會執行 model 的事件
viewElement.addEventListener('input', () => {
model.setNameValue(viewElement.name, viewElement.value)
})
// 當 model 發生變化時,會自動修改 view 的值
model.subscribe((attrName, newValue) => {
document.getElementsByName(attrName).forEach((elem) => {
elem.value = newValue.toUpperCase()
})
})
}
}
}
// View 純 HTML
<input type="text" name = "name" id="name">
// 使用時
const nameInput = document.getElementById('name');
const model = new Model()
const viewModel = new ViewModel(model);
viewModel.bind(nameInput, 'name');
我自已的看法 MVVM 有點感覺是給純前端使用,你可以想成幾乎每什麼商業邏輯,單純的重點就在於 :
『 畫面 』與 『 資料 』的 『 綁定 』
有點像是之前聽過的 vue 的『 雙向綁定 』,這樣感覺 vue 應該是以 MVVM 為基礎理念來設計,但是上網查了一下,知乎有一篇在討論這個主題,有興趣的看一下。不過先說好我是後端,對前端的事情不太熟喔
我的腦袋就是迸出了以下幾個詞 :
這兩個東西前端應該是非常的常聽到,我這裡比較想知道的是,這兩個的優缺比較,然後一下我覺得這篇文章還不錯,可以參考看看,不過我不是前端,不一定專業。
我突然想到,以後端的世界來說,很常會將資料存在 cache 與 db 中,這個應該有辦法進行『 雙向綁定的概念 』這樣當資料庫更新時,自動也會更新 cache 的資料。
我的感覺和馬克大找到的文章相似,雙向綁定用起來輕鬆方便,多數情境用起來都很舒服,但在比較複雜的情境會相對不好 Trace 資料/畫面變化的原因;相對的,單向綁定寫起來程式碼會多一點,但可以確定畫面的改變一定是因為資料改變導致的。